Qdrantのスナップショット保存先にS3バケットを指定してみた
リテールアプリ共創部@大阪の岩田です。
Qdrantには簡単にコレクションのスナップショットが取得できるという特徴があります。このスナップショットはデフォルトではQdrantが稼働しているマシンのローカルファイルシステムに保存されるのですが、設定ファイルを記述することでS3に保存することもできます。
このブログではQdrantのスナップショットをS3に保存する機能を試してみます。
環境
先日のブログで構築した環境を利用していきます。
また、EC2インスタンスに設定したIAMロールにはS3関連の必要な権限を設定していることとします。
やってみる
それではさっそくS3へのスナップショット取得を試していきましょう。
スナップショットをS3に保存するには、保存先のS3バケット等を指定するために設定ファイルを記述する必要があります。
スナップショット関連の設定はstorage
のsnapshots_config
配下に記述します。snapshots_storage
にs3
を指定することでスナップショットをS3に保存できます。さらにsnapshots_storage
にs3
を指定した場合は、s3_config
というキー配下に以下の設定が記述可能になります。
- bucket
- region
- access_key
- secret_key
- endpoint_url
それぞれの設定値の意味はキーの名前から推測できると思います。aws_session_token
には対応していないのがポイントですね。
ちょっとソースを追ってみたんですが、設定はこのあたりで定義していました。
実際にS3に書き込む処理はobject_store
というクレートを利用していて、上記Structで指定した設定値をobject_store::aws::AmazonS3Builderに
渡して利用するようです。
今回は以下のような設定ファイルを用意しました。
log_level: DEBUG
service:
host: 0.0.0.0
http_port: 6333
grpc_port: 6334
storage:
performance:
max_search_threads: 4
optimizers:
flush_interval_sec: 5
default_segment_number: 2
handle_collection_load_errors: true
snapshots_config:
snapshots_storage: s3
s3_config:
bucket: <スナップショット保存先のS3バケット名>
access_keyとsecret_keyは指定していませんが、EC2にアタッチしているIAMロールの権限をうまく使ってくれることを期待したいとろこです。
設定ファイルの準備ができたのでqdrantを起動します。
./target/release/qdrant
http://<EC2のGIP>:6333/dashboard#
にアクセスし、ダッシュボードからQuickstartのチュートリアルを実行し、コレクションを作成しておきます。
コレクションの準備ができたので、ダッシュボードのCollections
からTake Snapshot
を実行してみましょう。
Qdrantを実行しているターミナルに以下のようなログが出力されました。
2024-10-23T00:35:42.724603Z INFO collection::collection::snapshots: Creating collection snapshot star_charts-1725973526092207-2024-10-23-00-35-42.snapshot into "./snapshots/star_charts/star_charts-1725973526092207-2024-10-23-00-35-42.snapshot"
2024-10-23T00:35:42.783341Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/6c584b07-1f68-4c8d-bdc6-7c49b5dd0fce"
2024-10-23T00:35:42.803042Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/0fd931d0-61d1-46c7-9386-26457bf8252e"
2024-10-23T00:35:42.831097Z INFO object_store::aws::builder: Using Instance credential provider
2024-10-23T00:35:42.834634Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T00:35:42.835661Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T00:35:42.839806Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T00:35:42.840728Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T00:35:43.131525Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T00:35:43.142284Z INFO actix_web::middleware::logger: <アクセス元GIP> "POST /collections/star_charts/snapshots HTTP/1.1" 200 146 "http://<EC2のGIP>:6333/dashboard" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" 0.417870
ダッシュボードを確認すると無事にスナップショットが取得できていました。
S3のマネコンからもスナップショットが確認できました。
S3関連の権限が不足しているとどうなるか確認してみる
せっかくなのでIAMロールにS3関連の権限が不足しているとどうなるか確認してみました。
スナップショットの一覧表示
まずはS3関連の権限を全て削除した状態で確認
Internal Server Errorが表示されました。
ログには以下のようなエラーが出力されていました。
2024-10-23T00:51:14.755994Z INFO actix_web::middleware::logger: <アクセス元のGIP> "GET /collections/star_charts/cluster HTTP/1.1" 200 159 "http://<EC2のGIP>:6333/dashboard" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" 0.000217
2024-10-23T00:51:14.786604Z ERROR qdrant::actix::helpers: Error processing request: Service internal error: Failed to list snapshots: Generic S3 error: Error performing list request: Client error with status 403 Forbidden: <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>User: arn:aws:sts::<AWSアカウントID>:assumed-role/qdrant-role/i-00bf5989c46de63aa is not authorized to perform: s3:ListBucket on resource: "arn:aws:s3:::<S3バケット名>" because no identity-based policy allows the s3:ListBucket action</Message><RequestId>T1W6GZ1XSTF85Q3Q</RequestId><HostId>ixbMroj8TjbozjpXrhbheDj9u5OFLN3KgZEKL3Edpmwt8+/9y6gBv45PPrBk+YEUk5ahYFRRhnM=</HostId></Error>
2024-10-23T00:51:14.786818Z INFO actix_web::middleware::logger: <アクセス元のGIP> "GET /collections/star_charts/snapshots HTTP/1.1" 500 475 "http://<EC2のGIP>:6333/dashboard" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" 0.038616
s3:ListBucket
の権限が無いとのことなので、s3:ListBucket
の権限を付与した後に再度トライしてみます。今度はスナップショットの一覧は表示できました。
スナップショットの取得
続いて「TAKE SNAPSHOT」でスナップショットの取得を試みましたが、以下のエラーで失敗しました。
2024-10-23T00:55:44.524139Z INFO collection::collection::snapshots: Creating collection snapshot star_charts-1725973526092207-2024-10-23-00-55-44.snapshot into "./snapshots/star_charts/star_charts-1725973526092207-2024-10-23-00-55-44.snapshot"
2024-10-23T00:55:44.579451Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/6c584b07-1f68-4c8d-bdc6-7c49b5dd0fce"
2024-10-23T00:55:44.597493Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/0fd931d0-61d1-46c7-9386-26457bf8252e"
2024-10-23T00:55:44.623775Z INFO object_store::aws::builder: Using Instance credential provider
2024-10-23T00:55:44.626643Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T00:55:44.627335Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T00:55:44.627822Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T00:55:44.628345Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T00:55:44.670279Z ERROR qdrant::actix::helpers: Error processing request: Service internal error: failed to store snapshot archive to /home/ec2-user/qdrant/./storage/tmp/star_charts-1725973526092207-2024-10-23-00-55-44.snapshot-arc-3zKS4f: Service internal error: Failed to put multipart: The operation lacked the necessary privileges to complete for path snapshots/star_charts/star_charts-1725973526092207-2024-10-23-00-55-44.snapshot: Client error with status 403 Forbidden: <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>User: arn:aws:sts::<AWSアカウントID>:assumed-role/qdrant-role/i-00bf5989c46de63aa is not authorized to perform: s3:PutObject on resource: "arn:aws:s3:::<S3バケット名>/snapshots/star_charts/star_charts-1725973526092207-2024-10-23-00-55-44.snapshot" because no identity-based policy allows the s3:PutObject action</Message><RequestId>QYV3PPMQ920FGV0V</RequestId><HostId>Py6d09LtDdVcepfX2ljKwT1c0nW3Xg7cpD6kmHA7aYiEKygWiw0P/OGXK+jMuN6NKaQ4ZBvYPks=</HostId></Error>
2024-10-23T00:55:44.670493Z INFO actix_web::middleware::logger: <アクセス元GIP> "POST /collections/star_charts/snapshots HTTP/1.1" 500 609 "http://<EC2のGIP>:6333/dashboard" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" 0.146518
今度はs3:PutObject
の権限不足によって失敗しているようです。s3:PutObject
の権限を付与して再トライします。
2024-10-23T01:41:49.649262Z INFO collection::collection::snapshots: Creating collection snapshot star_charts-1725973526092207-2024-10-23-01-41-49.snapshot into "./snapshots/star_charts/star_charts-1725973526092207-2024-10-23-01-41-49.snapshot"
2024-10-23T01:41:49.706332Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/0fd931d0-61d1-46c7-9386-26457bf8252e"
2024-10-23T01:41:49.732051Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/6c584b07-1f68-4c8d-bdc6-7c49b5dd0fce"
2024-10-23T01:41:49.755223Z INFO object_store::aws::builder: Using Instance credential provider
2024-10-23T01:41:49.759264Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:41:49.760349Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:41:49.761307Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:41:49.761993Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T01:41:49.998938Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T01:41:50.007825Z ERROR qdrant::actix::helpers: Error processing request: Service internal error: failed to store snapshot archive to /home/ec2-user/qdrant/./storage/tmp/star_charts-1725973526092207-2024-10-23-01-41-49.snapshot-arc-qMbtmS: Service internal error: Failed to get head: The operation lacked the necessary privileges to complete for path snapshots/star_charts/star_charts-1725973526092207-2024-10-23-01-41-49.snapshot: Client error with status 403 Forbidden: No Body
2024-10-23T01:41:50.008359Z INFO actix_web::middleware::logger: <アクセス元のGIP> "POST /collections/star_charts/snapshots HTTP/1.1" 500 287 "http://<EC2のGIP>:6333/dashboard" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" 0.359175
今度はClient error with status 403 Forbidden: No Body
とのことです。具体的に何の権限不足かは分かりませんが、このエラーが出たときはS3上にオブジェクトは保存されていました。つまりPutObject成功後に何かしらの操作を行い、その操作に失敗したと考えられそうです。ということでs3:GetObject
あたりかな?と予想して権限を付与して再トライします。
2024-10-23T01:49:41.982639Z INFO collection::collection::snapshots: Creating collection snapshot star_charts-1725973526092207-2024-10-23-01-49-41.snapshot into "./snapshots/star_charts/star_charts-1725973526092207-2024-10-23-01-49-41.snapshot"
2024-10-23T01:49:42.038668Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/0fd931d0-61d1-46c7-9386-26457bf8252e"
2024-10-23T01:49:42.064042Z DEBUG segment::segment::entry: Taking snapshot of segment "./storage/collections/star_charts/0/segments/6c584b07-1f68-4c8d-bdc6-7c49b5dd0fce"
2024-10-23T01:49:42.085963Z INFO object_store::aws::builder: Using Instance credential provider
2024-10-23T01:49:42.088681Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:49:42.090754Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:49:42.091308Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:49:42.091887Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T01:49:42.280237Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T01:49:42.293251Z INFO actix_web::middleware::logger: <アクセス元のGIP> "POST /collections/star_charts/snapshots HTTP/1.1" 200 146 "http://<EC2のGIP>:6333/dashboard" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" 0.310688
今度は無事に成功しました!
スナップショットの削除
あとはスナップショットの削除も試しておきましょう。
2024-10-23T01:52:44.279980Z INFO object_store::aws::builder: Using Instance credential provider
2024-10-23T01:52:44.283507Z INFO storage::content_manager::snapshots: Deleting collection snapshot "./snapshots/star_charts/star_charts-1725973526092207-2024-10-23-00-35-42.snapshot"
2024-10-23T01:52:44.283591Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:52:44.284288Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:52:44.284771Z DEBUG reqwest::connect: starting new connection: http://169.254.169.254/
2024-10-23T01:52:44.285511Z DEBUG reqwest::connect: starting new connection: https://s3.us-east-1.amazonaws.com/
2024-10-23T01:52:44.311092Z ERROR qdrant::actix::helpers: Error processing request: Service internal error: Failed to delete snapshot: The operation lacked the necessary privileges to complete for path snapshots/star_charts/star_charts-1725973526092207-2024-10-23-00-35-42.snapshot: Client error with status 403 Forbidden: <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>User: arn:aws:sts::<AWSアカウントID>:assumed-role/qdrant-role/i-00bf5989c46de63aa is not authorized to perform: s3:DeleteObject on resource: "arn:aws:s3:::<S3バケット名>/snapshots/star_charts/star_charts-1725973526092207-2024-10-23-00-35-42.snapshot" because no identity-based policy allows the s3:DeleteObject action</Message><RequestId>G9S4A0H6PD864V3C</RequestId><HostId>r+VE8hWLRIQr0cqMfIdLUpm0mooOBVjDqgtV7P9c+8HG64JAEB1iQJKzUQ65dZEFnuTY7maVvas=</HostId></Error>
2024-10-23T01:52:44.311291Z INFO actix_web::middleware::logger: <アクセス元GIP> "DELETE /collections/star_charts/snapshots/star_charts-1725973526092207-2024-10-23-00-35-42.snapshot HTTP/1.1" 500 556 "http://<EC2のGIP>:6333/dashboard" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36" 0.031377
今度はs3:DeleteObject
が不足しているようなので権限を付与して再トライ...
無事削除に成功しました。
最終的にEC2用のIAMロールに割り当てた許可ポリシーは以下の通りでした。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::<S3バケット名>"
},
{
"Effect": "Allow",
"Action": [
"s3:DeleteObject",
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::<S3バケット名>/*"
}
]
}
まとめ
Qdrantのスナップショット機能を試してみました。やはりS3に保存できると安心感がありますね。
もし自前でQdrantのクラスタを運用することになったら、S3にスナップショットを保存するよう設定しておきたいところです。